﻿#pragma once
#define  _CRT_SECURE_NO_WARNINGS 1
# include<stdio.h>
# include<locale.h>
# include<Windows.h>
# include<stdbool.h>
# include<stdlib.h>
# include<time.h>

#define POS_X 24
#define POS_Y 5

#define WALL L'□'
#define BODY L'●'
#define FOOD L'★'

#define KEY_PRESS(vk) (((GetAsyncKeyState(vk)) & 1)? 1 : 0)


//类型的声明和函数的声明 都在头文件中

// 通过链表 来实现贪吃蛇的节点
typedef struct SnakeNode
{
	int x;
	int y;
	struct SnakeNode* next;
}SnakeNode, *pSnakeNode; // 我们还需要一个指针(pSnakeNode)指向蛇的头 
// ,号后面的指针等价于下面这个代码
//typedef struct SnakeNode* pSnakeNode;
/*
有了指向蛇头的指针之后，我们就可以找到蛇的头
 除了蛇头 我们还需要
 1.蛇的速度
 2.蛇的方向
 3.食物
 4.食物得分
 5.总分
 6.贪吃蛇的状态
 */

// 蛇的方向
enum DIRETION
{
	UP = 1,
	DOWN,
	LEFT,
	RIGHT
};

//蛇的状态
enum GAME_STATUS
{
	OK, // 正常
	KILL_BY_WALL,//撞墙
	KILL_BY_SELF,//撞到自己
	END_NORMAL//正常退出
};

// 贪吃蛇
typedef struct Snake
{
	pSnakeNode _pSnake;//指向蛇头的指针
	pSnakeNode _pFood;// 指向食物节点的指针
	enum DIRETION _dir;//蛇的方向
	enum GAME_STATUS _status;//游戏的状态（蛇的状态）
	int _food_weight; // 一个食物的分数
	int _score;//总分数
	int _sleep_time;//休息时间，休息时间决定蛇的速度快慢，休息越长，速度越慢。
}Snake, *pSnake;
// 这里的*pSnake等价于
// typedef struct Snake* pSnake; 

// 函数的声明

// 定位光标的位置
void SetPos(short x, short y);

// 游戏的初始化
void GameStart(pSnake ps); // 这个形参等价于 Snake* ps

// 欢迎界面的打印
void WelcomeToGame();
// 创建地图
void CreateMap();
// 初始化蛇身
void InitSnake(pSnake ps);
// 创建食物
void CreateFood(pSnake ps);


// 游戏的运行逻辑
void GameRun(pSnake ps);

// 贪吃蛇走一步的过程
void SnakeMove(pSnake ps);

//  判断下一步的节点坐标是否是食物
int NextIsFood(pSnakeNode pnext, pSnakeNode ps);
// 如果下一步的节点坐标 有食物就吃掉食物
void EatFood(pSnakeNode pnext, pSnake ps);
// 下一步的坐标不是食物
void NoFood(pSnakeNode pnext, pSnake ps);
// 检测下一步 蛇是否撞墙
void KillByWall(pSnake ps);
// 检测下一步 蛇是否撞到自己
void KillBySelf(pSnake ps);


// 游戏的善后工作
void GameEnd(pSnake ps);
